#include "crc-calculate.h"

/* CRC handler declaration */
CRC_HandleTypeDef   CrcHandle;

/**
* @brief Init CRC, use CRC-16/IBM(alias: CRC-16, CRC-16/ARC, CRC-16/LHA) CRC Calculator, polynomial is: x^16 + x^15 + x^2 + 1
*/
uint16_t LoRa_crc_calculate(uint8_t pBuffer[], uint8_t BufferLength)
{
    uint16_t uwCRCValue = 0;
    /*##-1- Configure the CRC peripheral #######################################*/
    CrcHandle.Instance = CRC;

    CrcHandle.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_DISABLE;
    CrcHandle.Init.GeneratingPolynomial    = 0x8005;
    CrcHandle.Init.DefaultInitValueUse	   = DEFAULT_INIT_VALUE_DISABLE;
    //RefIn: true
    CrcHandle.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_BYTE;
    //RefOut: true
    CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
    CrcHandle.Init.CRCLength               = CRC_POLYLENGTH_16B;
    CrcHandle.InputDataFormat              = CRC_INPUTDATA_FORMAT_BYTES;
    CrcHandle.Init.InitValue               = 0;

    /* DeInitializes the CRC peripheral */
    HAL_CRC_DeInit(&CrcHandle);

    /* Initialise CRC */
    HAL_CRC_Init(&CrcHandle);

    uwCRCValue = (uint16_t)HAL_CRC_Accumulate(&CrcHandle, (uint32_t *)pBuffer, (uint32_t)BufferLength);
    return uwCRCValue;
}

/**
* @brief CRC MSP Initialization
*        This function configures the hardware resources used in this example:
*           - Peripheral's clock enable
* @param hcrc: CRC handle pointer
* @retval None
*/
void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
{
    /* CRC Peripheral clock enable */
    __HAL_RCC_CRC_CLK_ENABLE();
}

/**
* @brief CRC MSP De-Initialization
*        This function freeze the hardware resources used in this example:
*          - Disable the Peripheral's clock
* @param hcrc: CRC handle pointer
* @retval None
*/
void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
{
    /* Enable CRC reset state */
    __HAL_RCC_CRC_FORCE_RESET();

    /* Release CRC from reset state */
    __HAL_RCC_CRC_RELEASE_RESET();
}
